/**
 * ReportGear(2011)
 */
package com.reportgear.report.model.cell.value;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.dom4j.Element;

import com.reportgear.report.model.cell.value.support.CorssDataValueObject;
import com.reportgear.report.model.script.Expression;
import com.reportgear.report.model.script.ScriptContext;
import com.sot.core.util.NumberUtils;
import com.sot.core.util.StringUtils;

/**
 * 交叉数据对象<br/>
 * 中间对象，外部不需要处理
 * 
 * @version 1.0 2011-4-10
 * @author <a herf="lexloo@gmail.com">lexloo</a>
 * @since Report 1.0
 */
public class CrossDataObject extends AbstractCellObject {
	private static final Pattern PAT_TEST = Pattern.compile("(D\\d+)");

	private List<Integer> xIds = new ArrayList<Integer>();
	private int y;
	// 根据XId值存储值
	private Map<Integer, Double> values = new HashMap<Integer, Double>();

	// X方向公式
	private String xFormula = "";

	private boolean calculated = false;
	private String value = "";

	@Override
	public String toString() {
		if (this.calculated) {
			return this.value;
		}

		String result;
		String formula = xFormula;

		if (StringUtils.isEmpty(formula)) {
			if (xIds.size() == 0) {
				result = "";
			} else {
				double dblValue = NumberUtils.convertToDouble(this.getValue(xIds.get(0)), 0.0D);
				if (Math.abs(dblValue) < 0.00001) {
					result = "";
				} else {
					result = String.valueOf(dblValue);
				}
			}
		} else {
			// 去掉所有非公式信息，如"岗位工资层级[3027858]+岗位工资[3011341]*12.5/ 12*(123)"转换为"[3027858]+[3011341]*125/12*(123)"
			formula = xFormula.replaceAll("[^\\d|+|-|*|/|\\[|\\]|(|)]", "");
			formula = formula.replaceAll("\\[(\\d+)\\]", "D$1");
			Matcher m = PAT_TEST.matcher(formula);
			while (m.find()) {
				String fg = m.group(1);
				formula = formula.replaceAll(fg, StringUtils.convertToString(this.getValue(NumberUtils
						.convertToInteger(fg.substring(1), 0))));
			}

			Expression expr = ScriptContext.INSTANCE.getExpression();

			// TODO 这儿是不是要优化
			double dblValue = NumberUtils.convertToDouble(expr.eval(formula), 0.0D);
			if (Math.abs(dblValue) < 0.00001) {
				result = "";
			} else {
				result = String.valueOf(dblValue);
			}

		}

		this.value = result;
		this.calculated = true;

		return this.value;
	}

	/**
	 * 添加id对应的值
	 * 
	 * @param id
	 *            id
	 * @param value
	 *            值
	 */
	public void addValue(int xId, int yId, double value) {
		if (xIds.contains(xId) && this.y == yId) {
			this.values.put(xId, this.getValue(xId) + value);
		}
	}

	/**
	 * 根据薪酬数据计算值
	 * 
	 * @param valueObjects
	 *            值对象
	 */
	public void addValues(List<CorssDataValueObject> valueObjects) {
		for (CorssDataValueObject so : valueObjects) {
			this.addValue(so.x_Id, so.y_Id, so.value);
		}
	}

	/**
	 * 获取Id对应的值
	 * 
	 * @param id
	 *            id
	 * @return 对应的值
	 */
	public double getValue(int id) {
		return NumberUtils.convertToDouble(this.values.get(id), 0);
	}

	public List<Integer> getxIds() {
		return xIds;
	}

	public void setY(int y){
		this.y = y;
	}

	public int getY() {
		return y;
	}

	public void setXFormula(String xFormula) {
		this.xFormula = xFormula;
	}

	public String getXFormula() {
		return xFormula;
	}

	@Override
	public void read(Element parent) {
		throw new UnsupportedOperationException();
	}

	@Override
	public void write(Element parent) {
		throw new UnsupportedOperationException();
	}
}
